package com.qf.qfarticle.controller.feign;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qf.qfarticle.service.ApArticleService;
import com.qf.qfleadnewsfeignapi.article.ApArticleApi;
import com.qf.qfleadnewsmodel.article.pojos.ApArticle;
import com.qf.qfleadnewsmodel.article.vos.ApArticleVo;
import com.qf.qfleadnewsmodel.commons.consts.RedisConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class ApArticleApiFeign implements ApArticleApi {

    @Autowired
    private ApArticleService apArticleService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void computeHot() {
        //先查询article表中过去两周的文章数据
        Calendar instance = Calendar.getInstance();
        //获取过去15天的日期
        instance.add(Calendar.DAY_OF_MONTH,-15);

        Date last15Days = instance.getTime();
        Wrapper<ApArticle> qw = Wrappers.lambdaQuery(ApArticle.class)
                .ge(ApArticle::getPublishTime,last15Days);
        List<ApArticle> apArticles = apArticleService.list(qw);

        //对这些数据进行热度排序.
        List<ApArticleVo> apArticleVos = apArticles.stream().map(apArticle -> {
            ApArticleVo vo = new ApArticleVo();
            BeanUtils.copyProperties(apArticle, vo);

            //计算当前article的分数
            double score = computeScore(apArticle);
            vo.setScore(score);
            return vo;
        }).sorted().limit(30).collect(Collectors.toList());

        log.info("按照行为热度排序后的顺序为：{}",apArticleVos);

        String key = RedisConst.ARTICLE_HOT_CACHE_PREFIX + "__all__";
        String value = JSON.toJSONString(apArticleVos);
        redisTemplate.opsForValue().set(key,value);

        //todo: 查询每个频道中前30位的数据，分别按照频道id进行缓存

    }

    /**
     * 根据用户的行为，计算文章的热度分值
     * @param apArticle
     * @return
     */
    private double computeScore(ApArticle apArticle) {
        Long id = apArticle.getId();

        //获取文章的阅读数
        Long readNum = 0l;
        try {
            readNum = Long.parseLong(redisTemplate.opsForValue().get(RedisConst.ARTICLE_READ_PREFIX + id));
        }catch (Exception e){}
        //获取文章点赞数
        Long likeNum = 0l;
        //获取文章的收藏数
        Long collectionNum = 0l;
        try(RedisConnection connection = redisTemplate.getConnectionFactory().getConnection()){
            likeNum = connection.bitCount((RedisConst.ARTICLE_LIKE_PREFIX + id).getBytes(StandardCharsets.UTF_8));
            collectionNum = connection.bitCount((RedisConst.ARTICLE_COLLECTION_PREFIX + id).getBytes(StandardCharsets.UTF_8));
        }

        double score = readNum * RedisConst.BEHAVIOR_READ_WEIGHT
                + likeNum * RedisConst.BEHAVIOR_LIKE_WEIGHT
                + collectionNum * RedisConst.BEHAVIOR_COLLECTION_WEIGHT;

        return score;
    }

}
